package lambda;



import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author 江岸
 * @version V1.0
 * @ClassName: CollectMethods
 * @description:
 * @date 2020/11/3016:46
 * @since V1.0
 */
public class CollectMethods {
    public static void main(String[] args) {
        System.out.println(1<<0);
        System.out.println(1<<1);
        System.out.println(1<<2);
        System.out.println(1<<3);

        //fun6();
    }

    //Map&Reduce
    public static void fun1() {
        List<Integer> integers = Arrays.asList(10, 20, 30, 40, 50, 60);
        // <入参，结果> 一定要有返回值
        Function<Integer, Double> doubleFunction = (cost) -> cost + .12 * cost;
        //.map方法 相当于把每个元素都用方法执行一次。得到新元素，返回stream流
        Stream<Double> doubleStream = integers.stream().map(doubleFunction);
        doubleStream.forEach(System.out::println);

        List<Integer> arr = Arrays.asList(10, 20, 30, 40);
        // reduce() 函数可以将所有值合并成一个。相当于sum = {sum + cost}
        Stream<Integer> stream = arr.stream();
        //Optional<Integer> reduce = stream.reduce((sum, cost) -> sum + cost); 结果100，下面的结果-80。 sum代表前一个元素，cost代表后一个元素
        Optional<Integer> reduce = stream.reduce((sum, cost) -> sum - cost);
        System.out.println(reduce.get());

    }

    public static void fun2() {
        Product a = new Product(1, "A");
        Product b = new Product(2, "B");
        Product c = new Product(7, "C");
        List<Product> products = Arrays.asList(a, b, c);
        Function<Product, Product> function = (p) -> p.setAgeReturn(p.getAge() + 1);
        products.stream().map(function).forEach(System.out::println);
        System.out.println("------------------------------------");
        //sum一直都是A cost分别是b，c
        Product product = products.stream().map(function).reduce((sum, cost) -> sum.setAgeReturn(cost.getAge())).get();
        System.out.println(product);
    }

    /**
     * 著作权归https://pdai.tech所有。
     * 链接：https://www.pdai.tech/md/java/java8/java8-stream.html
     *
     * Collectors.joining(", ")
     * Collectors.toList()
     * Collectors.toSet() ，生成set集合
     * Collectors.toMap(MemberModel::getUid, Function.identity())
     * Collectors.toMap(ImageModel::getAid, o -> IMAGE_ADDRESS_PREFIX + o.getUrl())
     */
    public static void fun3() {
        // 将字符串换成大写并用逗号链接起来
        List<String> G7 = Arrays.asList("USA", "Japan", "France", "Germany", "Italy", "U.K.", "Canada");
        String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", "));
        System.out.println(G7Countries);
    }

    //flatMap 将多个stream连成一个stream
    public static void fun4(){
        List<Integer> A = Arrays.asList(1, 2, 3);
        List<Integer> B = Arrays.asList(5, 6, 7);
        //flatMap返回一个流，该流包括将流中的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容而得到的结果
        List<Integer> collect = Stream.of(A, B).flatMap(o -> o.stream()).collect(Collectors.toList());
        System.out.println(collect);
    }

    //distinct去重 count计数
    public static void fun5(){
        Product a = new Product(1, "A");
        Product b = new Product(2, "B");
        Product BB = new Product(2, "BB");
        Product c = new Product(7, "C");
        List<Product> products = Arrays.asList(a, b, BB, c);
        List<Product> collect = products.stream().map(Product::getObj).distinct().collect(Collectors.toList());
        System.out.println(collect.get(0)==a);
        System.out.println("---------------------------------------------------------");
        System.out.println( products.stream().map(Product::getAge).distinct().collect(Collectors.toList()));
        System.out.println("---------------------------------------------------------");
        List<Product> s = products.stream().map((o) -> new Product(o.getAge(),"ss")).collect(Collectors.toList());
        System.out.println(s);
        List<Integer> integers = Arrays.asList(1, 2, 3, 3, 4, 5, 5, 6);
        System.out.println(integers.stream().filter((o)-> o>3).count());
    }

    //Collections类
    public static void fun6(){
        List<Integer> list = new ArrayList<Integer>();
        for(int i = 0; i < 10; i++) {
            list.add(i);
        }
        System.out.println("原始的顺序：" + list);
        Collections.shuffle(list);
        System.out.println("打乱后顺序：" + list);
        System.out.println("二分查找20：" + Collections.binarySearch(list, 20));
        System.out.println("二分查找2：" + Collections.binarySearch(list, 2));
        Collections.sort(list);
        //二分查找需要排序后使用
        System.out.println("进行排序后：" + list);
        System.out.println("二分查找20：" + Collections.binarySearch(list, 20));
        System.out.println("二分查找2：" + Collections.binarySearch(list, 2));
    }
}
